import junit.framework.TestCase;

import de.unibi.comet.util.BitArray;

public class BitArrayTest extends TestCase {
	
	public void test() {
		BitArray ba = new BitArray(200);
		assertEquals(200, ba.size());
		for (int i=0; i<200; ++i) assertFalse(ba.get(i));
		try { 
			ba.get(-1);
			fail();
		} catch (IndexOutOfBoundsException e) {}
		try { 
			ba.get(200);
			fail();
		} catch (IndexOutOfBoundsException e) {}
		try { 
			ba.set(-1, true);
			fail();
		} catch (IndexOutOfBoundsException e) {}
		try { 
			ba.set(200, true);
			fail();
		} catch (IndexOutOfBoundsException e) {}
		ba.set(0, true);
		ba.set(10, true);
		ba.set(20, true);
		ba.set(63, true);
		ba.set(128, true);
		ba.set(193, true);
		for (int i=0; i<200; ++i) {
			if ((i==0) || (i==10) || (i==20) || (i==63) || (i==128) || (i==193)) {
				assertTrue(String.format("Offending value: %d", i), ba.get(i));
				continue;  
			}
			assertFalse(String.format("Offending value: %d", i), ba.get(i));
		}
	}
	
	public void testIterator() {
		BitArray ba = new BitArray(200);
		ba.set(0, true);
		ba.set(4, true);
		ba.set(7, true);
		ba.set(63, true);
		ba.set(65, true);
		int n=0;
		for (boolean b : ba) {
			if ((n==0)||(n==4)||(n==7)||(n==63)||(n==65)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		assertEquals(200,n);
	}

	public void testShift1() {
		BitArray ba = new BitArray(200);
		ba.set(0, true);
		ba.set(4, true);
		ba.set(7, true);
		ba.set(62, true);
		ba.set(63, true);
		ba.set(65, true);
		ba.shiftLeft();
		int n=0;
		for (boolean b : ba) {
			if ((n==1)||(n==5)||(n==8)||(n==63)||(n==64)||(n==66)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		n=0;
		ba.shiftLeft();
		for (boolean b : ba) {
			if ((n==2)||(n==6)||(n==9)||(n==64)||(n==65)||(n==67)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		ba.shiftRight();
		n=0;
		for (boolean b : ba) {
			if ((n==1)||(n==5)||(n==8)||(n==63)||(n==64)||(n==66)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		ba.shiftRight();
		n=0;
		for (boolean b : ba) {
			if ((n==0)||(n==4)||(n==7)||(n==62)||(n==63)||(n==65)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		ba.shiftRight();
		n=0;
		for (boolean b : ba) {
			if ((n==3)||(n==6)||(n==61)||(n==62)||(n==64)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
	}
	
	public void testShift2() {
		BitArray ba1 = new BitArray(200);
		ba1.set(198, true);
		ba1.set(199, true);
		ba1.shiftLeft();
		BitArray ba2 = new BitArray(200);
		ba2.set(199, true);
		assertTrue(ba1.compareTo(ba2)==0);
	}

	public void testShift3() {
		BitArray ba = new BitArray(36);
		ba.set(0, true);
		ba.set(2, true);
		ba.set(3, true);
		ba.shiftLeft();
		int n=0;
		for (boolean b : ba) {
			if ((n==1)||(n==3)||(n==4)) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
	}

	public void testShift4() {
		BitArray ba = new BitArray(64);
		ba.set(0, true);
		ba.shiftLeft();
		int n=0;
		for (boolean b : ba) {
			if (n==1) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
	}
	
	public void testAndOr() {
		BitArray ba1 = new BitArray(64);
		BitArray ba2 = new BitArray(64);
		BitArray ba3 = new BitArray(64);
		ba1.set(63, true);
		ba2.set(63, true);
		ba1.and(ba2);
		int n=0;
		for (boolean b : ba1) {
			if (n==63) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
		ba1.and(ba3);
		for (boolean b : ba1) assertFalse(String.format("Offending value: %d", n),b);
		ba1.or(ba2);
		n=0;
		for (boolean b : ba1) {
			if (n==63) assertTrue(String.format("Offending value: %d", n),b);
			else assertFalse(String.format("Offending value: %d", n),b);
			++n;
		}
	}
	
	public void testToString() {
		BitArray ba = new BitArray(70);
		ba.set(0, true);
		ba.set(4, true);
		ba.set(7, true);
		ba.set(62, true);
		ba.set(63, true);
		ba.set(65, true);
		assertEquals("(0000101100000000000000000000000000000000000000000000000000000010010001)", ba.toString());
	}
}
